﻿using System;

using OpenTK;

namespace MosCraft.Utilities
{
    public class Perlin
    {
        private int seed;
        private int octave;
        
        public Perlin(int seed, int octave)
        {
            this.seed = seed;
            this.octave = octave;
        }

        public double getNoiseLevelAtPosition(int x, int z)
        {
            int xmin = (int)(double)x / octave;
            int xmax = xmin + 1;
            int zmin = (int)(double)z / octave;
            int zmax = zmin + 1;

            Vector2d a = new Vector2d(xmin, zmin);
            Vector2d b = new Vector2d(xmax, zmin);
            Vector2d c = new Vector2d(xmax, zmax);
            Vector2d d = new Vector2d(xmin, zmax);

            double ra = getRandomAtPosition(a);
            double rb = getRandomAtPosition(b);
            double rc = getRandomAtPosition(c);
            double rd = getRandomAtPosition(d);

            double ret = cosineInterpolate( //Interpolate Z direction
                    cosineInterpolate((float)ra, (float)rb, (float)(x - xmin * octave) / octave), //Interpolate X1
                    cosineInterpolate((float)rd, (float)rc, (float)(x - xmin * octave) / octave), //Interpolate X2
                    ((float)z - (float)zmin * (float)octave) / (float)octave);
            return ret;
        }

        private float cosineInterpolate(float a, float b, float x)
        {
            float ft = (x * MathHelper.Pi);
            float f = (float)((1f - QuickMath.Cos(ft)) * .5f);
            float ret = a * (1f - f) + b * f;
            return ret;
        }
        private double getRandomAtPosition(Vector2d coord)
        {
            Random rand = new Random((int)(10000 * (Math.Sin(coord.X) + Math.Cos(coord.Y) + Math.Tan(seed))));
            //FastRandom test = new FastRandom((int)(10000 * (Math.Sin(coord.getX()) + Math.Cos(coord.getZ()) + Math.Tan(seed))));
            //return test.NextDouble();
            return rand.NextDouble();
        }
    }
}
